'use strict';

// 1. 练习一  
// 不要使用 JavaScript 内置的 parseInt() 函数，利用 map 和 reduce 操作实现一个string2int()函数：
// 方案一
// function string2int(s) {  
//     return s*1;

// };

// 方案二
function string2int(s) {// 大函数（方法）开始
    var m=s.split("");// 用变量来接，split() 方法用于把一个字符串分割成字符串数组
    // console.log(m);//先将字符串分割成数组
    function toInt(abc){// 制定一个函数（方法）
        return +abc;// 将元素类型转换为数值类型
        }// 将元素类型转换为数值类型函数结束	
    var n=m.map(toInt);// 用变量来接=字符串分割后的字符串数组(制定的函数)，将函数作用到每一个元素上
    // console.log(n);//将元素类型转换为数值类型
    return n.reduce(function(x,y){// 返回结果：装有字符串分割后的字符串数组的变量.reduce()将元素与下一个元素进行计算，将结果再与下一个元素进行计算，直到结束
        return x*10+y;// 函数体（再经过计算，转化为一串数值）
        
    })// reduce()函数结束
}// string2int()函数（方法）结束

// 测试:
if (string2int('0') === 0 && string2int('12345') === 12345 && string2int('12300') === 12300) {
    if (string2int.toString().indexOf('parseInt') !== -1) {
        console.log('请勿使用parseInt()!');
    } else if (string2int.toString().indexOf('Number') !== -1) {
        console.log('请勿使用Number()!');
    } else {
        console.log('测试通过!');
    }
}
else {
    console.log('测试失败!');
}  
// reduce()
// var arr=[1,2,3,4];

// var index= arr.reduce(
//     function(x,y) {
//         return x*10+y;
//     }
// )
// console.log(index);

// 2. 练习二
// 请把用户输入的不规范的英文名字，变为首字母大写，其他小写的规范名字。输入：['adam', 'LISA', 'barT']，输出：['Adam', 'Lisa', 'Bart']。
function normalize(arr) {// 制定函数
    function fn(word){ // 制定规范字母大小写的函数（形参）
        var list='';// 用空字符串来装数组中的元素
        for (var i = 0; i < word.length; i++) {
            if (i===0){// 用循环
                list+=word[i].toUpperCase();// 将首字母变为大写
            } 
            else{
                list+=word[i].toLowerCase();// 除了首字母大写，将其他字母变成小写
            }
        }
        return list;// 返回结果数组
    }
    return arr.map(fn);// 将函数作用在数组中的每个元素上
}

// 测试:
if (normalize(['adam', 'LISA', 'barT']).toString() === ['Adam', 'Lisa', 'Bart'].toString()) {
    console.log('测试通过!');
}
else {
    console.log('测试失败!');
}

// 3. 练习三
// 小明希望利用map()把字符串变成整数，他写的代码很简洁：
var arr = ['1', '2', '3'];
// var r;
// r= arr.map(parseInt);

// console.log(r);
// 结果竟然是1, NaN, NaN，小明百思不得其解，请帮他找到原因并修正代码。

// 提示：参考Array.prototype.map()的文档。

// 答案：parseInt() 只返回字符串中的第一个数字！如果第一个字符不能转换为数字，parseInt() 返回 NaN
// parseInt(string, radix)将一个字符串 string 转换为 radix 进制的整数， radix 为介于 2-36 之间的数。
// map() 方法是向传递给他的函数中传递三个参数，分别为当前值，当前索引以及整个数组
// 而 parseInt() 函数接收两个参数：需要转换的字符串，以及进制基数
// 所以，整个语句可以写作：['1', '7', '11'].map((value, index, array) => parseInt(value, index, array))
// array 被 parseInt 舍弃之后，得到的结果分别是：parseInt('1', 0)、parseInt('7', 1) 以及 parseInt('11', 2)
// 也就是上面看到的 [1, NaN, NaN]

// 正确的写法应该是：

var r= arr.map(arr => parseInt(arr, 10));
console.log(r);

// 4. 练习四
// 请尝试用filter()筛选出素数：
// 注意：filter() 把传入的函数依次作用于每个元素，然后根据返回值是 true 还是 false 决定保留还是丢弃该元素(if判断)
function get_primes(arr) {
        let result = [];// 制定一个空数组
        result = arr.filter(function(x){// 用空数组来接收filter()筛选后的数组结果(形参)
            if(x === 2)// 当形参为2时
                return x;// 返回结果2
            else if(x != 1){// 当形参不等于1时（素数里没有1）
                let flag = 1;// 定义一个判断变量=1
                for(let j = 2; j<=Math.sqrt(x) ;j++){// 进入循环，若无特殊情况条件限制，当j小于形参的平方根时，停止循环（Math.sqrt()方法返回一个数的平方根）
                    if(x % j === 0){// 判断当形参除以j=2没有余数时，一般素数都不能被2整除
                        flag = 0;// 判断变量变为0，为不符合素数条件
                        break;// 跳过循环
                    }
                }
                if(flag === 1)// 如果判断变量=1，则符合条件
                    return x;// 返回符合条件的结果，即为素数
            }
        })
        return result;//返回最终数组筛选结果，都为素数的数组
    }

// 测试:
var
    x,
    r,
    arr = [];
for (x = 1; x < 100; x++) {
    arr.push(x);// 向数组尾部添加新的元素
}
r = get_primes(arr);
if (r.toString() === [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97].toString()) {
    console.log('测试通过!');
} else {
    console.log('测试失败: ' + r.toString());
}